#include "Base64ToBinary.h"

/* Devuelve el numero asociado al char del Alfabeto64 */
int findPositionInAlphabet(char symbol) {
	int position = 100; /* Posicion invalida */
	int j;
	for (j = 0; j < 64; j++) {
		if (ALPHABET[j] == symbol) {
			position = j;
			break;
		}
	}
	return position;
}

int toBinary(const unsigned char* buffer, int length, unsigned char* resultBuff) {

	uint8_t n[4]; /* 4 bytes de 6 bits cada uno*/
	int noPadBytes = 0;
	/* Analizo cada byte de los 4 que tengo */
	int i;
	for (i = 0; i < 4; i++) {
		if (buffer[i] != '=') {
			uint8_t byte = findPositionInAlphabet(buffer[i]);
			checkValidBase64(byte);
			n[i] = byte;
			noPadBytes++; // Cuento cuantos caracteres distintos de = tengo
		} else {
			n[i] = 0;
		}
	}
	resultBuff[0] = (n[0] << 2) + (n[1] >> 4);
	resultBuff[1] = (n[1] << 4) + (n[2] >> 2);
	resultBuff[2] = (n[2] << 6) + n[3];
	return noPadBytes;
}

int base64ToBinary(FILE* input, FILE* output) {

	fflush(output);
	int counter = 0; // Cuenta cada byte que lee
	int c = fgetc(input);
	checkReadError(input);
	unsigned char buffer[4]; // Leo de a 4 caracteres siempre
	unsigned char tmpResult[3];
	int length = 0;
	while (1) {
		counter++;
		if (c == EOF) {
			break;
		} else {
			buffer[counter - 1] = c; /* Acumulo el byte en el array */
			if (counter == 4) { /* Ya tengo 4 bytes, lo convierto */
				length = toBinary(buffer, counter, tmpResult);
				fwrite((void*) tmpResult, 1, length-1, output);
				checkWriteError(output);
				counter = 0;
			}
		}
		c = fgetc(input);
		checkReadError(input);
	}
	//Devuelve un 0 si no hubo errores
	return EXIT_SUCCESS;
}
